// Molecule.h: interface for the Molecule class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_MOLECULE_H__D115815A_4F65_11D1_93BC_006097737B41__INCLUDED_)
#define AFX_MOLECULE_H__D115815A_4F65_11D1_93BC_006097737B41__INCLUDED_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#include "Atom.h"
#include "Translate.h"
#include <fstream>
#include <iostream>
using namespace std;
#include <cstdlib>
#include <string>
#include <vector>



class Molecule  
{
public:

	Molecule(int i_NInput, char *ZmatrixFile);
	virtual ~Molecule();

	// return uniform random values to TestInput
	void createRandomSol(double *TestInput);

  // move just i'th coordinate, where i=0 here refer to first 
  // coordinate
  void customModifySol(double *TestInput, int i);

	Position* Build(double *Value);
  Position* Build(vector<double> &Value);
	void TransformDerivatives(Position *XDerivative, double *InputDerivative);

	void PrintFractional(double *Value, double ChiSq, char name[], int NAccept, int NTotal);
	void PrintCartesians(double *Value);
  // create file named name
  void PrintCIF(double *Value, const double ChiSq, char name[]);
  // append to stream out
  void PrintCIF(double *Value, const double ChiSq, ofstream& out, string cifLabel = "default");

  double distanceFromInputZmatrix(double *solution);
	
	int  GetNAtom(void)		
	{ 
	return (NAtom); 
	}

	void GetDiffractorInput(Position* &W1, Position* &W2, Position* &W3)
	{
	W1   = &WaveVector1;
	W2   = &WaveVector2;
	W3   = &WaveVector3;
	}

	void GetSpaceGroup(char SG[15])
	{
  	strcpy_s(SG, 15, SpaceGroup);
	}

  // get atom label to calculate FiniteFactor array in Diffraction
  char** getLabels() {return atomLabel;}

private:
	int      NAtom, NInput;

	Position *AtomPosition;
	
	 Atom      **AtomBuilder;	
	 double    *InputValue;
   double    *ZmatrixInputValue;  // used in distanceFromInputZmatrix
	 int       **InputOnX;
	 Pack      *Derivative;
	 Position  *P1, *P2, *P3;  // translation reference frame virtual atoms
	 Position  UnitCell1, UnitCell2, UnitCell3;
	 Translate *Mover;
	 char      SpaceGroup[15];
	 double abc[3]; // a, b, c unit length in aa. For printing out in PrintCartesians. 
   double abg[3]; // alpha, beta, gamma in degrees.
	 char **atomLabel;

	Position WaveVector1, WaveVector2, WaveVector3;
	void BuildDependence(void);
  void CopyVA(double *InputValue, vector<double> &Input, int NInput);

	int NMolecule; // no. of molecules in asym cell
	int *NAtomEach; // no. of atoms in each molecule

  double getDistanceBetweenAngles(double &a1, double &a2);
};

#endif // !defined(AFX_MOLECULE_H__D115815A_4F65_11D1_93BC_006097737B41__INCLUDED_)
